﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using Windows.Storage;
using Windows.System.UserProfile;
using System.Linq;
using Windows.UI.Xaml;
using SeriesManager.Model;
using SeriesManager.Enum;
using SeriesManager.Model.Comparer;
using SeriesManager.API;

namespace SeriesManager.ViewModel
{
    public class AppX : BindableBase
    {
        #region Singleton

        private static AppX instance;

        private AppX() 
        {
            this.Series = new ObservableCollection<SeriesModel>();
            this.Series.CollectionChanged += Series_CollectionChanged;
            
            if (ApplicationData.Current.RoamingSettings.Values.ContainsKey("Theme"))
            {
                System.Enum.TryParse(ApplicationData.Current.RoamingSettings.Values["Theme"].ToString(), out this.theme);
            }

            this.AirDay = new List<EpisodeModel>();
            this.AirWeek = new List<EpisodeModel>();
            this.AirMonth = new List<EpisodeModel>();
            this.AirYear = new List<EpisodeModel>();
            this.AirOther = new List<EpisodeModel>();
            
            this.API = new TVDB();
        }

        public static AppX Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new AppX();
                }
                return instance;
            }
        }

        #endregion

        private SeriesModel current;
        private bool navigationBarIsOpen;
        private ElementTheme theme = ElementTheme.Dark;

        #region DataProperties

        public IApi API
        {
            get;
            private set;
        }

        public bool NavigationBarIsOpen
        {
            get { return this.navigationBarIsOpen; }
            set { SetProperty(ref this.navigationBarIsOpen, value); }
        }

        public ElementTheme Theme 
        {
            get 
            {
                return theme;
            }
            set
            {
                if (!ApplicationData.Current.RoamingSettings.Values.ContainsKey("Theme") || ApplicationData.Current.RoamingSettings.Values["Theme"].ToString() != value.ToString())
                {
                    ApplicationData.Current.RoamingSettings.Values["Theme"] = value.ToString();
                    SetProperty(ref this.theme, value);
                }
            }
        }
        public List<EpisodeModel> AirDay { get; private set; }
        public List<EpisodeModel> AirWeek { get; private set; }
        public List<EpisodeModel> AirMonth { get; private set; }
        public List<EpisodeModel> AirYear { get; private set; }
        public List<EpisodeModel> AirOther { get; private set; }
        public SeriesModel Current
        {
            get { return this.current; }
            set { SetProperty(ref this.current, value); }
        }
        public Languages Language
        {
            get
            {
                Languages lang = Languages.English;

                var first =  GlobalizationPreferences.Languages.FirstOrDefault();
                if (first != null && first.StartsWith("de"))
                {
                    lang = Languages.Deutsch;
                }

                if (ApplicationData.Current.RoamingSettings.Values.ContainsKey("Language"))
                    System.Enum.TryParse(ApplicationData.Current.RoamingSettings.Values["Language"].ToString(), out lang);
                return lang;
            }
            set
            {
                if (!ApplicationData.Current.RoamingSettings.Values.ContainsKey("Language") || ApplicationData.Current.RoamingSettings.Values["Language"].ToString() != value.ToString())
                {
                    ApplicationData.Current.RoamingSettings.Values["Language"] = value.ToString();
                    OnPropertyChanged();

                    foreach (SeriesModel series in this.Series.Where(S => S.Subscription))
                    {
                        series.Language = value;
                        this.API.Update(series);
                    }
                }
            }
        }
        public ObservableCollection<SeriesModel> Series { get; private set; }

        #endregion

        private void Series_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems == null) return;

            foreach (SeriesModel series in e.NewItems)
            {
                series.PropertyChanged += series_PropertyChanged;
                if (series.Subscription)
                {
                    LoadAirs(series);
                }
            }
        }
        private void series_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName.Equals("Subscription"))
            {
                SeriesModel series = sender as SeriesModel;

                if (series.Subscription)
                {
                    LoadAirs(series);
                    if (series.Poster != null)
                    {
                        series.Poster.DownloadImage();
                    }
                }
                else
                {
                    RemoveAirs(series);
                }
            }
        }
        private void LoadAirs(SeriesModel series)
        {
            var comparer = new EpisodeComparer(true);

            this.AirDay.AddRange(series.AirToday);
            this.AirDay.Sort(comparer);
            OnPropertyChanged("AirDay");

            this.AirWeek.AddRange(series.AirWeek);
            this.AirWeek.Sort(comparer);
            OnPropertyChanged("AirWeek");

            this.AirMonth.AddRange(series.AirMonth);
            this.AirMonth.Sort(comparer);
            OnPropertyChanged("AirMonth");

            this.AirYear.AddRange(series.AirYear);
            this.AirYear.Sort(comparer);
            OnPropertyChanged("AirYear");

            this.AirOther.AddRange(series.AirOther);
            this.AirOther.Sort(comparer);
            OnPropertyChanged("AirOther");
        }
        private void RemoveAirs(SeriesModel series)
        {
            this.AirDay.RemoveAll(E => E.Season.Series.ID == series.ID);
            OnPropertyChanged("AirDay");
            this.AirWeek.RemoveAll(E => E.Season.Series.ID == series.ID);
            OnPropertyChanged("AirWeek");
            this.AirMonth.RemoveAll(E => E.Season.Series.ID == series.ID);
            OnPropertyChanged("AirMonth");
            this.AirYear.RemoveAll(E => E.Season.Series.ID == series.ID);
            OnPropertyChanged("AirYear");
            this.AirOther.RemoveAll(E => E.Season.Series.ID == series.ID);
            OnPropertyChanged("AirOther");
        }
    }
}

